#include <bits/stdc++.h>

#define in read()
#define fi first
#define se second
#define pb push_back
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)

using namespace std;

using ll = long long;
using db = double;
using pii = pair < int, int >;
using tl = tuple < int, int, int >;
using vec = vector < int >;
using veg = vector < pii >;

int read() {
    int x = 0; bool f = 0; char ch = getchar(); while(!isdigit(ch)) f |= ch == '-',ch = getchar();
    while(isdigit(ch)) x = x * 10 + (ch ^ 48),ch = getchar(); return f ? -x : x;
}

const int N = 1e4 + 10;
const int M = 3e5 + 10;
const int inf = 0x3f3f3f3f;

int S, T, h[N], cnt = 1, tp[N], bel[N], low[N], dfn[N], stk[N], top, d[N], now[N], tim, scc, n, m;
int x[M], y[M];
bool vis[N];
vec G[N];

struct edge { int v, w, nxt; } e[M << 1];
void tlink(int x, int y, int w) { e[++cnt] = (edge) { y, w, h[x] }; h[x] = cnt;}
void link(int x, int y, int w) { tlink(x, y, w); tlink(y, x, 0); }

void tarjan(int x) {
	low[x] = dfn[x] = ++tim; vis[x] = true; stk[++top] = x;
	for(int i = h[x], y; i; i = e[i].nxt)
		if(e[i].w) {
			if(!dfn[y = e[i].v]) tarjan(y), low[x] = min(low[x], low[y]);
			else if(vis[y]) low[x] = min(low[x], dfn[y]);
		}
	if(low[x] == dfn[x]) {
		int y; ++scc;
		do {
			y = stk[top--]; vis[y] = 0; bel[y] = scc;
		} while(y ^ x);
	}
}
bool bfs() {
	rep(i, 0, n + 1) d[i] = 0; queue < int > q; q.push(S); now[S] = h[S]; d[S] = 1;
	while(q.size()) {
		int x = q.front(); q.pop();
		for(int i = h[x], y; i; i = e[i].nxt) 
			if(e[i].w && !d[y = e[i].v]) {
				d[y] = d[x] + 1; now[y] = h[y]; q.push(y); if(y == T) return true;
			}
	}
	return false;
}
int dfs(int x, int flow) {
	if(x == T) return flow;
	int res = flow;
	for(int i = now[x], y; i && res; i = e[i].nxt) {
		now[x] = i;
		if(e[i].w && d[y = e[i].v] == d[x] + 1) {
			int k = dfs(y, min(res, e[i].w));
			if(!k) d[y] = 0;
			res -= k; e[i].w -= k; e[i ^ 1].w += k;
		}
	} return flow - res;
}

void cdfs(int x, int c) {
	tp[x] = c;
	for(auto y : G[x])
		if(!tp[y]) cdfs(y, c ^ 1);
		else assert(tp[y] != c);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
	n = in, m = in; S = 0; T = n + 1;
	rep(i, 1, m) {
		x[i] = in, y[i] = in;
		G[x[i]].pb(y[i]); G[y[i]].pb(x[i]);
	}
	rep(i, 1, n) if(!tp[i]) cdfs(i, 2);
	rep(i, 1, n)
		if(tp[i] == 2) {
			link(S, i, 1);
			for(auto y : G[i]) link(i, y, 1);
		} else link(i, T, 1);
	int mxflow = 0, flow; while(bfs()) while(flow = dfs(S, inf)) mxflow += flow;
	rep(i, 0, T) if(!dfn[i]) tarjan(i);
	veg ans;
	for(int si = h[S], x; si; si = e[si].nxt) if(e[si].w == 0) {
			x = e[si].v;
			for(int i = h[x], y; i; i = e[i].nxt)
				if(!e[i].w && bel[x] != bel[y = e[i].v] && y){
					ans.pb(minmax(x, y));
				}
		}
	sort(ans.begin(), ans.end()); printf("%lu\n", ans.size());
	for(auto v : ans) printf("%d %d\n", v.fi, v.se);
	return 0;
}
